package com.gitee.cnlongdb.server.operator.query;

import java.io.File;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.alibaba.fastjson.JSON;
import com.gitee.cnlongdb.basic.constant.LongDbConstant;
import com.gitee.cnlongdb.basic.entity.database.LongTableEntity;
import com.gitee.cnlongdb.basic.entity.matchingrule.MatchingReadWrite;
import com.gitee.cnlongdb.basic.entity.query.LongDbJoinWhere;
import com.gitee.cnlongdb.basic.entity.query.LongDbQuery;
import com.gitee.cnlongdb.basic.entity.query.LongDbWhere;
import com.gitee.cnlongdb.basic.entity.query.QueryResultEntity;
import com.gitee.cnlongdb.basic.entity.query.QueryThreadEntity;
import com.gitee.cnlongdb.basic.enums.sysnc.LongdbDataSyncEnms;
import com.gitee.cnlongdb.basic.enums.where.LongDbWhereType;
import com.gitee.cnlongdb.basic.exception.SocketConnectRefuseException;
import com.gitee.cnlongdb.basic.utils.FieldHandlerUtils;
import com.gitee.cnlongdb.basic.utils.GenerateSequenceUtils;
import com.gitee.cnlongdb.basic.utils.ListSortUtils;
import com.gitee.cnlongdb.basic.utils.LongFileOperator;
import com.gitee.cnlongdb.basic.utils.MySortList;
import com.gitee.cnlongdb.basic.utils.RandomUtil;
import com.gitee.cnlongdb.monitor.table.CnLongTableSummary;
import com.gitee.cnlongdb.server.config.LongdbConfigHandler;
import com.gitee.cnlongdb.server.connect.LongDbConnect;
import com.gitee.cnlongdb.server.connect.nettymission.LongdbNettyClient;
import com.gitee.cnlongdb.server.threads.query.QueryHandlerThread;

/**
 * 系统名称：QueryOperator.java
 * 模块名称：
 * 模块描述：longdb - 查询引擎对象
 * 功能列表：
 * 模块作者：ZOUYONG
 * 开发时间：2018年12月5日 下午9:50:59
 * 模块路径：com.gitee.cnlongdb.server.operator.query.QueryOperator
 * 更新记录：
 */
public class QueryOperator {

	private final Logger logger = (Logger) LoggerFactory.getLogger(QueryOperator.class);
	
	// 数据库连接对象
	private LongDbConnect connect;
	public QueryOperator(LongDbConnect connect) {
		logger.debug(LongDbConstant.longdbDefaultName + "初始化[查询执行器]...");
		this.connect = connect;
	}

	/**
	 * 功能描述：指定表名查询全部
	 * 模块作者：ZOUYONG
	 * 开发时间：2018年11月11日 上午9:04:39
	 * 更新记录：
	 * 返回数据：List<T>
	 */
	@SuppressWarnings("unchecked")
	public <T> List<T> findAll(Class<T> cls, String tableName, String yearMothDayArys) {
		List<Object> objectList = new ArrayList<Object>();
		if(null == cls || StringUtils.isBlank(tableName)) {
			return (List<T>) objectList;
		}
		LongDbQuery query = new LongDbQuery();
		query.setClassz(cls);
		query.setTableName(tableName);
		query.setYearMothDayArys(yearMothDayArys);
		return find(query);
	}

	/**
	 * 功能描述：指定表名-条件查询
	 * 模块作者：ZOUYONG
	 * 开发时间：2018年11月11日 上午9:07:42
	 * 更新记录：
	 * 返回数据：List<T>
	 */
	public <T> List<T> find(LongDbQuery query) {
		return findAll(query);
	}
	
	/**
	 * 功能描述：条件查询
	 * 模块作者：ZOUYONG
	 * 开发时间：2018年11月11日 下午5:05:52
	 * 返回数据：List<T>
	 * @param query 查询条件对象
	 */
	@SuppressWarnings("unchecked")
	private <T> List<T> findAll(LongDbQuery query) {
		
		if(null == query || null == query.getClassz()) {
			return new ArrayList<T>();
		}
		Class<?> cls = query.getClassz();
		String tableName = StringUtils.isBlank(query.getTableName()) ? cls.getSimpleName() : query.getTableName();
		query.setTableName(tableName);
		
		// 如果需要分页，且分页参数都为0，则直接返回空
		if(query.isNeedPage() && (query.getPageSize() <= 0 || query.getPageNo() < 0)) {
			return new ArrayList<T>();
		}
 
		// 单次查询最大值，起始数量值
		Integer total = query.getPageSize(), start = query.getPageNo();
		if(query.isNeedPage()) {
			if(query.getPageNo() == 0) {
				query.setPageNo(1);
			}
			total = query.getPageNo() * query.getPageSize();
			start = query.getPageNo() * query.getPageSize() - query.getPageSize();
		}
		query.setTotal(total);
		query.setStart(start);
		
		Object object = executeFindAll(query);
		if(query.isQueryCount()) { // 如果只查询数量
			return new ArrayList<T>();
		}
		return (List<T>) object;
	}

	/**
	 * 功能描述：进行读写分离判断
	 × 模块作者：ZOUYONG
	 × 开发时间：2018年12月24日 下午2:10:38
	 × 返回数据：List<T>
	 */
	public Object executeFindAll(LongDbQuery query) {
		// 获取读数据库的列表
		List<MatchingReadWrite> matchingList = 
				LongdbConfigHandler.getMatchingRuleListByConnect(connect, LongDbConstant.longdbReadConnect);
		if(CollectionUtils.isNotEmpty(matchingList)) {
			List<Integer> numList = new ArrayList<Integer>();
			return findRemote(query, matchingList, numList);
		}
		return findLocal(query);
	}

	/**
	 * 功能描述：执行本机查询操作
	 × 模块作者：ZOUYONG
	 × 开发时间：2018年12月24日 下午4:27:09
	 × 返回数据：Object
	 */
	public Object findLocal(LongDbQuery query) {
		// 多线程查询数据
		List<String> strList = execMoreThreadQueryData(query);
		if(query.isQueryCount()) {
			return query;
		}
		// 是否有关联查询
		strList = execJoinQueryData(strList, query);
		// 排序 和 分页处理
		return pageSortString(strList, query);
	}
	
	/**
	 * 功能描述：执行远程查询操作
	 × 模块作者：ZOUYONG
	 × 开发时间：2018年12月25日 上午9:25:28
	 × 返回数据：Object
	 */
	private Object findRemote(LongDbQuery query, List<MatchingReadWrite> matchingList, List<Integer> numList) {
		Random rand = new Random();
		int numSize = rand.nextInt(matchingList.size());
		if(matchingList.size() > 1) {
			while(numList.contains(numSize)) {
				numSize = rand.nextInt(matchingList.size());
			}
		}
		MatchingReadWrite matching = matchingList.get(numSize);
		numList.add(numSize);
		// 是否本机查询
		if(connect.getDataBaseIp().equals(matching.getDataBaseIp()) && connect.getDataBasePort() == matching.getDataBasePort()) {
			return findLocal(query);
		}
		// 发起远程查询
		else {
			try {
				Map<String, Object> requestMap = new HashMap<String, Object>();
				query.setTransObject(false); // 如果远程查询，则不需要转换对象
				requestMap.put(LongDbConstant.longdbActuatorQuery, query);
				// 发送网络消息
				Map<String, String> sendMap = LongdbNettyClient.sendNettyMessageByLongdb(matching.getDataBaseIp(), matching.getDataBasePort(), requestMap);
				String requestResult = sendMap.get(LongdbDataSyncEnms.returnObject.name());
				if(StringUtils.isNotBlank(requestResult) && 
						LongdbDataSyncEnms.success.name().equals(sendMap.get(LongdbDataSyncEnms.returnCode.name()))) {
					if(query.isQueryCount()) {
						LongDbQuery resQuery = JSON.parseObject(requestResult, LongDbQuery.class);
						query.setQueryTotalCount(resQuery.getQueryTotalCount());
						return query;
					}
					List<String> dataList = JSON.parseObject(requestResult, List.class);
					List<Object> objectList = new ArrayList<Object>();
					for (String content : dataList) {
						objectList.add(FieldHandlerUtils.parserLongStrToObject(content, query.getClassz()));
					}
					return objectList;
				} else {
					logger.error("发起远程查询异常：{}", requestResult);
				}
				return new ArrayList<Object>();
			}
			catch (Exception e) {
				if(e instanceof SocketConnectRefuseException 
						&& matchingList.size() > 1 && matchingList.size() != numList.size()) {
					return findRemote(query, matchingList, numList); // 如果某个服务没有启动，则循环调用其他服务
				}
				throw new RuntimeException(e);
			}
		}
	}

	/**
	 * 功能描述：关联查询
	 × 模块作者：ZOUYONG
	 × 开发时间：2018年12月5日 上午9:29:06
	 × 返回数据：List<String>
	 */
	private List<String> execJoinQueryData(List<String> strList, LongDbQuery query) {
		
		if(CollectionUtils.isEmpty(strList) || query.getJoinWhereList().size() <= 0) {
			return strList;
		}
		// 汇总多个关联查询
		List<LongDbQuery> queryList = new ArrayList<LongDbQuery>();
		for (String content : strList) {
			for (LongDbJoinWhere joinWhere : query.getJoinWhereList()) {
				if(StringUtils.isBlank(joinWhere.getWhereTableName()) || StringUtils.isBlank(joinWhere.getJoinTableName())) {
					break;
				}
				LongDbQuery joinQuery = new LongDbQuery();
				joinQuery.setClassz(query.getClass());
				joinQuery.setTableName(joinWhere.getJoinTableName());
				joinQuery.setTotal(query.getTotal());
				List<LongDbWhere> whereList = new ArrayList<LongDbWhere>();
				whereList.addAll(joinWhere.getOnWhereList());
				whereList.addAll(joinWhere.getAndWhereList());
				for (LongDbWhere longDbWhere : whereList) {
					if(longDbWhere.getType().equals(LongDbWhereType.eq.name())) {
						longDbWhere.in(ListSortUtils.forceGetFieldString(content, longDbWhere.getWhereKey()));
					}
					joinQuery.longWhereMap.put(longDbWhere.getJoinKey(), longDbWhere);
				}
				queryList.add(joinQuery);
			}
		}
		if(CollectionUtils.isEmpty(queryList)) {
			return strList;
		}
		
		// 循环多个关联查询，合并查询结果
		for(LongDbQuery joinQuery : queryList) {
			List<String> joinList = execMoreThreadQueryData(joinQuery);
			if(CollectionUtils.isEmpty(joinList)) {
				continue;
			}
			for (LongDbJoinWhere joinWhere : query.getJoinWhereList()) {
				List<LongDbWhere> joinWhereList = joinWhere.getOnWhereList();
				int start = 0;
				for (int i=0; i<joinList.size(); i++) {
					boolean isJoinQuery = false;
					for (int j=0; j<strList.size(); j++) {
						String content = joinList.get(i);
						for (LongDbWhere longDbWhere : joinWhereList) {
							if(!longDbWhere.isJoin()) {
								break;
							}
							String whereValue = ListSortUtils.forceGetFieldString(strList.get(j), longDbWhere.getWhereKey());
							String joinValue = ListSortUtils.forceGetFieldString(content, longDbWhere.getJoinKey());
							if(whereValue == joinValue || whereValue.equals(joinValue)) {
								isJoinQuery = true;
							} else {
								isJoinQuery = false;
							}
						}
						if(!isJoinQuery) {
							continue;
						}
						if(joinWhere.getAliasMap().size() > 0) {
							content = updateContent(joinWhere.getAliasMap(), content);
						}
						// 如果关联查询到符合条件的数据，则合并数据
						if(strList.size() > start) {
							strList.set(start, strList.get(j)+content);
						} else {
							strList.add(strList.get(j)+content);
						}
						joinList.remove(i); i--;
						start++;
						break;
					}
				}
			}
		}
		
		return strList;
	}

	/**
	 * 功能描述：根据别名重新设置数据内容
	 × 模块作者：ZOUYONG
	 × 开发时间：2018年12月5日 上午9:59:45
	 × 返回数据：String
	 */
	private String updateContent(Map<String, String> aliasMap, String content) {
		
		if(StringUtils.isBlank(content) || null == aliasMap || aliasMap.size() == 0) {
			return content;
		}
		Map<String, Object> dataMap = FieldHandlerUtils.parserLongStrToMap(content);
		for(Iterator<String> iter = aliasMap.keySet().iterator(); iter.hasNext(); ) {
			String key = iter.next();
			if(null != dataMap.get(key)) {
				dataMap.put(aliasMap.get(key), dataMap.get(key));
				dataMap.remove(key);
			}
		}
		return FieldHandlerUtils.parserLongMapToStr(dataMap);
	}

	/**
	 * 功能描述：执行多线程查询结果
	 × 模块作者：ZOUYONG
	 × 开发时间：2018年11月28日 下午4:44:11
	 × 返回数据：List<String>
	 */
	public List<String> execMoreThreadQueryData(LongDbQuery query) {
		
		List<String> strList = new ArrayList<String>();
		LongTableEntity table = connect.getCreateOperator().getLongTableByName(query.getTableName());
		if(null == table) {
			return strList;
		}
		
		// 获取所有的数据文件
		List<File> list = getTableDataFiles(query, query.getTableName());
		if(CollectionUtils.isEmpty(list)) {
			return strList;
		}

		// 定义线程需要的对象 
		String requestId = RandomUtil.getCharAndNumr(14);
		List<QueryThreadEntity> threadList = new ArrayList<QueryThreadEntity>();
		for(File file : list) {
			if(null != query && StringUtils.isNotBlank(query.getYearMothDayArys()) 
					&& !calcAppointRangeTime(file.getName(), query.getYearMothDayArys())) {
				continue;
			}
			QueryThreadEntity queryData = new QueryThreadEntity();
			queryData.setRequestId(requestId);
			queryData.setQuery(query);
			queryData.setFile(file);
			queryData.setCurrThreadId(RandomUtil.getCharAndNumr(14));
			queryData.setTotalCount(query.getTotal()); // 设置此次查询最大数量
			threadList.add(queryData);
		}
		
		QueryResultEntity queryResult = new QueryResultEntity();
		ExecutorService executor = Executors.newCachedThreadPool(); // 定义线程池
		CountDownLatch doneSignal = new CountDownLatch(threadList.size());
		for (QueryThreadEntity queryData : threadList) {
			executor.submit(new QueryHandlerThread(queryData, doneSignal, connect, queryResult));
		}
		try {
			doneSignal.await(); // 等待所有线程完成操作
		} catch (InterruptedException e) {
			logger.error(e.getMessage());
			throw new RuntimeException("获取查询结果异常：" + e.getMessage());
		} finally {
			executor.shutdown(); // 关闭线程池
		}
		query.setQueryTotalCount(queryResult.getCurrQueryCount());
		
		for (QueryThreadEntity queryData : threadList) {
			if(CollectionUtils.isEmpty(queryData.getObjectList())) {
				continue;
			}
			strList.addAll(queryData.getObjectList());
		}
		return strList;
	}
	
	/**
	 * 功能描述：排序 和 分页处理
	 * 模块作者：ZOUYONG
	 * 开发时间：2018年12月4日 下午8:45:28
	 * 更新记录：
	 * 返回数据：List<Object>
	 */
	public List<Object> pageSortString(List<String> strList, LongDbQuery query) {
		query.setQueryTotalCount(CollectionUtils.isNotEmpty(strList) ? strList.size() : 0l);
		List<Object> objectList = new ArrayList<Object>();
		// 排序处理
		if(CollectionUtils.isNotEmpty(strList) && CollectionUtils.isNotEmpty(query.getSortList())) {
			MySortList.sortString(strList, query.getSortList());
		}
		// 是否需要分割
		if(null!= query.getPageSize() && strList.size() > query.getPageSize()) {
			Integer total = query.getTotal();
			Integer start = query.getStart();
			try {
				if(strList.size() < total) {
					total = strList.size();
				}
				strList = strList.subList(start, total);
			} catch(Exception e) {
				logger.error(e.getMessage(), e);
			}
		}
		for (String content : strList) {
			objectList.add(query.isTransObject() ? 
				FieldHandlerUtils.parserLongStrToObject(content, query.getClassz()) : content);
		}
		return objectList;
	}

	/**
	 * 功能描述：根据表分区配置获取表中所有的数据文件
	 * 模块作者：ZOUYONG
	 * 开发时间：2018年11月22日 下午9:27:24
	 * 更新记录：
	 * 返回数据：List<File>
	 */
	public List<File> getTableDataFiles(LongDbQuery query, String tableName) {
		// 获取表中所有的数据文件
		List<File> list = CnLongTableSummary.getFileByTableName(this.connect, tableName);
		if(null != query && query.getLongWhereMap().size() > 0) {
			List<File> temp = new ArrayList<File>();
			Map<String, LongDbWhere> longWhereMap = query.getLongWhereMap();
			for(Iterator<String> iter = longWhereMap.keySet().iterator(); iter.hasNext(); ) {
				String key = iter.next();
				LongDbWhere where = longWhereMap.get(key);
				if(where.isTableMatching()) {
					for (int i=0; i<list.size(); i++) {
						File file = list.get(i);
						if(!temp.contains(file) && file.getPath().indexOf(
								File.separator + where.getStartValue().toString() + File.separator) >= 0) {
							temp.add(file);
						}
					}
				}
			}
			if(CollectionUtils.isNotEmpty(temp)) {
				list = temp;
			}
		}
		
		ListSortUtils.sortFileList(list, true);
		for (int i=0; i<list.size(); i++) {
			File file = list.get(i);
			if(file.length() == 0) {
				list.remove(i);
				i--;
			}
		}
		return list;
	}

	/**
	 * 功能描述：获取符合条件查询出来表的内容
	 * 模块作者：ZOUYONG
	 * 开发时间：2018年11月11日 下午12:03:33
	 * 更新记录：
	 * 返回数据：List<String>
	 */
	@SuppressWarnings("unchecked")
	public List<String> getTableContentJson(LongDbQuery query, Class<?> cls, String tableName) {
		List<String> jsonList = new ArrayList<String>();
		if(null == query || query.longWhereMap.size() <= 0) {
			return jsonList;
		}
		if(StringUtils.isBlank(tableName)) {
			tableName =  cls.getSimpleName();
		}
		query.setTransObject(false);
		query.setTableName(tableName);
		return (List<String>) executeFindAll(query);
	}
	
	/**
	 * 功能描述：【查询匹配】返回内容
	 × 模块作者：ZOUYONG
	 × 开发时间：2018年11月26日 上午11:43:43
	 × 返回数据：String
	 */
	public <T> boolean whereString(String jsonStr, LongDbQuery query, Class<T> cls) {
		Map<String, Object> longMap = FieldHandlerUtils.parserLongStrToMap(jsonStr);
		if(query.longWhereMap.size() == 0 || getWhereObject(longMap, query, cls)) {
			return true;
		}
		return false;
	}

	/**
	 * 功能描述：执行【查询匹配】操作
	 × 模块作者：ZOUYONG
	 × 开发时间：2018年11月26日 上午11:41:05
	 × 返回数据：boolean
	 */
	public boolean getWhereObject(Map<String, Object> longMap, LongDbQuery query, Class<?> cls) {
		boolean filterStatus = false;
		for(Iterator<String> iter = query.longWhereMap.keySet().iterator(); iter.hasNext(); ) {
			String key = iter.next();
			LongDbWhere dbWhere = query.longWhereMap.get(key);
			if(null == dbWhere.getStartValue() || StringUtils.isBlank(dbWhere.getType())) {
				break; // 如果有值为空 或 没有指定查询类型，则直接查询结果为空
			}
			Object value = longMap.get(key);
			if(null == value) {
				continue;
			}
			filterStatus = execQueryOperator(dbWhere, value);
			// 是否有or查询
			if(!filterStatus && CollectionUtils.isNotEmpty(dbWhere.getOrWheres())) {
				for (LongDbWhere longDbWhere : dbWhere.getOrWheres()) {
					filterStatus = execQueryOperator(longDbWhere, value);
					if(filterStatus) {
						break;
					}
				}
			}
			if(!filterStatus) {
				break;
			}
		}
		return filterStatus;
	}
	
	/**
	 * 功能描述：字符串进行匹配
	 * 模块作者：ZOUYONG
	 * 开发时间：2018年11月27日 下午10:07:16
	 * 更新记录：
	 * 返回数据：boolean
	 */
	public boolean getWhereString(LongDbQuery query, String content) {
		if(StringUtils.isBlank(content)) {
			return false;
		}
		if(null == query || query.longWhereMap.size() == 0) {
			return true;
		}
		boolean filterStatus = false;
		for(Iterator<String> iter = query.longWhereMap.keySet().iterator(); iter.hasNext(); ) {
			String key = iter.next();
			LongDbWhere dbWhere = query.longWhereMap.get(key);
			if(null == dbWhere.getStartValue() || StringUtils.isBlank(dbWhere.getType())) {
				break; // 如果有值为空 或 没有指定查询类型，则直接查询结果为空
			}
			String value = ListSortUtils.forceGetFieldString(content, key);
			filterStatus = execQueryOperator(dbWhere, value);
			// 是否有or查询
			if(!filterStatus && CollectionUtils.isNotEmpty(dbWhere.getOrWheres())) {
				for (LongDbWhere longDbWhere : dbWhere.getOrWheres()) {
					filterStatus = execQueryOperator(longDbWhere, value);
					if(filterStatus) {
						break;
					}
				}
			}
			if(!filterStatus) {
				break;
			}
		}
		return filterStatus;
	}

	/**
	 * 功能描述：执行查询匹配操作
	 * 模块作者：ZOUYONG
	 * 开发时间：2018年11月10日 下午11:18:24
	 * 更新记录：
	 * 返回数据：boolean
	 */
	private boolean execQueryOperator(LongDbWhere longDbWhere, Object value) {
		boolean filterStatus = false;
		Object longdbVal = longDbWhere.getStartValue();
		if(null == longdbVal) {
			return filterStatus;
		}
		String queryType = longDbWhere.getType();
		// 相等查询
		if(queryType.equals(LongDbWhereType.is.name()) || queryType.equals(LongDbWhereType.eq.name())) {
			if(value == longdbVal || value.toString().equals(longdbVal.toString())) {
				filterStatus = true;
			}
		}
		// in查询
		else if(queryType.equals(LongDbWhereType.in.name())) {
			if(longdbVal instanceof List) {
				Collection<?> coll = (Collection<?>) longdbVal;
				if(coll.contains(value)) {
					filterStatus = true;
				}
			}
		}
		// like查询
		else if(queryType.equals(LongDbWhereType.like.name())) {
			if(value.toString().indexOf(longdbVal.toString()) >= 0) {
				filterStatus = true;
			}
		}
		// 大于查询
		else if(queryType.equals(LongDbWhereType.large.name())) {
			try {
				BigDecimal start = new BigDecimal(value.toString());
				BigDecimal end = new BigDecimal(longdbVal.toString());
				if(start.compareTo(end) == 1) {
					filterStatus = true;
				}
			} catch(Exception e) {
				logger.error("大于查询异常：" + e.getMessage());
			}
		}
		// 大于等于查询
		else if(queryType.equals(LongDbWhereType.largeq.name())) {
			try {
				BigDecimal start = new BigDecimal(value.toString());
				BigDecimal end = new BigDecimal(longdbVal.toString());
				if(start.compareTo(end) >= 0) {
					filterStatus = true;
				}
			} catch(Exception e) {
				logger.error("大于查询异常：" + e.getMessage());
			}
		}
		// 小于查询
		else if(queryType.equals(LongDbWhereType.small.name())) {
			try {
				BigDecimal start = new BigDecimal(value.toString());
				BigDecimal end = new BigDecimal(longdbVal.toString());
				if(start.compareTo(end) == -1) {
					filterStatus = true;
				}
			} catch(Exception e) {
				logger.error("小于查询异常：" + e.getMessage());
			}
		}
		// 小于等于查询
		else if(queryType.equals(LongDbWhereType.smallq.name())) {
			try {
				BigDecimal start = new BigDecimal(value.toString());
				BigDecimal end = new BigDecimal(longdbVal.toString());
				if(start.compareTo(end) <= 0) {
					filterStatus = true;
				}
			} catch(Exception e) {
				logger.error("小于查询异常：" + e.getMessage());
			}
		}
		// 区间查询
		else if(queryType.equals(LongDbWhereType.between.name())) {
			
			Object startValue = longDbWhere.getStartValue();
			Object endValue = longDbWhere.getEndValue();
			boolean isRes = false;
			if(null != longDbWhere.getCls()) {
				isRes = true;
				if(longDbWhere.getCls().equals(Date.class)) { // 日期
					if(((Date) value).getTime() >= ((Date) startValue).getTime() 
							&& ((Date) value).getTime() <= ((Date) endValue).getTime() ) {
						filterStatus = true;
					}
				}
				else if(longDbWhere.getCls().equals(Integer.class)) { // 数字比较大小
					try {
						if(Integer.valueOf(value.toString()) >= Integer.valueOf(startValue.toString()) && 
								Integer.valueOf(value.toString()) <= Integer.valueOf(endValue.toString())) {
							filterStatus = true;
						}
					} catch(Exception e) {
						logger.error("Between区间查询异常：" + e.getMessage());
						filterStatus = false;
					}
				}
			}
			/**
			 * 字符串比较大小：compareTo方法
			 * 如果指定的数与参数相等返回0。
			 * 如果指定的数小于参数返回 -1。
			 * 如果指定的数大于参数返回 1
			 */
			if(!isRes) {
				if(startValue.toString().compareTo(value.toString()) <= 0
						&& endValue.toString().compareTo(value.toString()) >= 0) {
					filterStatus = true;
				}
			}
		}
		return filterStatus;
	}

	/**
	 * 功能描述：根据主键ID查询-指定表名
	 * 模块作者：ZOUYONG
	 * 开发时间：2018年11月11日 上午9:12:09
	 * 更新记录：
	 * 返回数据：T
	 */
	public <T> T findById(String longId, Class<T> cls, String tableName) {

		String content = findContentById(longId, tableName);
		if(StringUtils.isBlank(content)) {
			return null;
		}
		try {
			return (T) FieldHandlerUtils.parserLongStrToObject(content, cls);
		} catch(Exception e) {
			logger.error(e.getMessage(), e);
			return null;
		}
	}

	/**
	 * 功能描述：根据ID获取数据内容
	 * 模块作者：ZOUYONG
	 * 开发时间：2018年12月8日 下午12:15:09
	 * 更新记录：
	 * 返回数据：String
	 */
	public String findContentById(String longId, String tableName) {
		// 数据所在文件中的行号
		Integer position = GenerateSequenceUtils.getLongDataOrder(longId);
		// 文件名称
		String fileName = longId.substring(10, longId.length());
		File tableIdFile = getFileByFileName(tableName, fileName);
		if(null == tableIdFile || !tableIdFile.exists() || null == position) {
			logger.error("要查找的ID数据不存在！");
			return null;
		}
		return LongFileOperator.readFileSomeLineData(tableIdFile, position);
	}
	
	/**
	 * 功能描述：获取指定表中的指定文件名称的文件
	 × 模块作者：ZOUYONG
	 × 开发时间：2018年12月27日 上午11:00:36
	 × 返回数据：File
	 */
	public File getFileByFileName(String tableName, String fileName) {
		if(StringUtils.isBlank(tableName) || StringUtils.isBlank(fileName)) {
			return null;
		}
		// 获取表中所有的数据文件
		List<File> list = CnLongTableSummary.getFileByTableName(this.connect, tableName);
		for (File file : list) {
			if(file.getName().equals(fileName)) {
				return file;
			}
		}
		return null;
	}

	/**
	 * 功能描述：根据条件查询一条数据 - 指定表名
	 * 模块作者：ZOUYONG
	 * 开发时间：2018年11月11日 上午9:14:04
	 * 更新记录：
	 * 返回数据：T
	 */
	@SuppressWarnings("unchecked")
	public <T> T findOne(LongDbQuery query) {
		if(null == query || query.longWhereMap.size() <= 0 || null == query.getClassz()) {
			return null;
		}
		Class<?> cls = query.getClassz();
		String tableName = StringUtils.isBlank(query.getTableName()) ? cls.getSimpleName() : query.getTableName();
		List<File> list = getTableDataFiles(null, tableName);
		for (File file : list) {
			// 获取文件内容
			String jsonStr = LongFileOperator.readFileOneLine(file);
			// 对文件内容进行刷选
			if(whereString(jsonStr, query, cls)) {
				return (T) FieldHandlerUtils.parserLongStrToObject(jsonStr, cls);
			}
		}
		return null;
	}

	/**
	 * 功能描述：查询表的总数量
	 * 模块作者：ZOUYONG
	 * 开发时间：2018年11月11日 下午4:49:58
	 * 更新记录：
	 * 返回数据：long
	 */
	public long count(String tableName, String yearMothDayArys) {
		long count = 0;
		if(StringUtils.isBlank(tableName)) {
			return count;
		}
		LongTableEntity table = connect.getCreateOperator().getLongTableByName(tableName);
		if(null == table) {
			return count;
		}
		ConcurrentHashMap<String, Integer> dataFileRowCountMap = table.getDataFileRowCountMap();
		for(Iterator<String> iter = dataFileRowCountMap.keySet().iterator(); iter.hasNext(); ) {
			String fileName = iter.next();
			if(calcAppointRangeTime(fileName, yearMothDayArys)) {
				Integer number = dataFileRowCountMap.get(fileName);
				if(null != number) {
					count += number;
				}
			}
		}
		return count;
	}

	/**
	 * 功能描述：计算时间和文件名称是否相符
	 × 模块作者：ZOUYONG
	 × 开发时间：2018年12月22日 下午3:33:08
	 × 返回数据：boolean
	 */
	private boolean calcAppointRangeTime(String fileName, String yearMothDayArys) {
		if(StringUtils.isBlank(yearMothDayArys)) {
			return true;
		}
		boolean status = false;
		String[] dateAry = yearMothDayArys.split("&");
		for (String dateStr : dateAry) {
			String[] twoDateAry = dateStr.split(";");
			int startTime = 0, endTime = 0; 	// 查询开始 和 结束时间
			int fileTime = Integer.valueOf(fileName.substring(0, 8));	// 文件时间
			if(twoDateAry.length == 1) {
				String[] timeAry = twoDateAry[0].split("-");
				startTime = Integer.valueOf(timeAry[0]+timeAry[1]+timeAry[2]);
				endTime = startTime;
			}
			else if(twoDateAry.length > 1) {
				String[] startAry = twoDateAry[0].split("-");
				startTime = Integer.valueOf(startAry[0]+startAry[1]+startAry[2]);
				String[] endAry = twoDateAry[1].split("-");
				endTime = Integer.valueOf(endAry[0]+endAry[1]+endAry[2]);;
			}
			if(fileTime >= startTime && fileTime <= endTime) {
				status = true;
				break;
			}
		}
		return status;
	}

	/**
	 * 功能描述：根据条件查询总数 - 指定表名
	 * 模块作者：ZOUYONG
	 * 开发时间：2018年11月11日 下午4:49:36
	 * 更新记录：
	 * 返回数据：long
	 */
	public long count(LongDbQuery query) {
		query.setQueryCount(true);	// 只查询数量
		query.setNeedPage(false);	// 不需要分页
		findAll(query);
		query.setQueryCount(false);
		query.setNeedPage(true);
		return null != query.getQueryTotalCount() ? query.getQueryTotalCount() : 0;
	}

}
